#ifndef skyString_h__
#define skyString_h__
#include "./skyObject.h"
namespace Sky
{
class StringBuilder;
typedef RefPtr<StringBuilder> StringBuilderPtr;
class String : public Object
{
	DECL_RTTI1(String,Object);
private:
	class stringNode
	{
	protected:
		friend class String;
		const TChar* _str;
		TInt _size;
	public:
		stringNode(const TChar* str,TInt size):_str(str)
		{
			if(size == -1)
				_size = String::getStringLength(str) + sizeof(TChar);
			else
				_size = size;
		}
	};
public:
	class staticString : public stringNode
	{
	public:
		staticString(const TChar* const str,TInt size = -1):stringNode(str,size){}
	};
	class dynamicString : public stringNode
	{
	public:
		dynamicString(const TChar* str,TInt size = -1):stringNode(str,size){}
		//dynamicString(TInt size):stringNode((TChar*)Memory::alloc(size),size){}
	};
	class managedString : public stringNode
	{
	public:
		managedString(TChar* str,TInt size = -1):stringNode(str,size){}
		managedString(TInt size):stringNode((TChar*)Memory::alloc(size),size){(const_cast<TChar*>(_str))[0] = _XT('\0');}
	};
	static TInt getStringLength(const TChar* str)
	{
		//return (TInt)skyStrlen(str);
		TInt l = 0;
		if(str == vNull)return 0;
		TChar* p = const_cast<TChar*>(str);
		while(p)
		{
			 l++;
			 p++;
		}
		return l;
	}
	static TBool compare(const StringPtr& str1,const StringPtr& str2);
	static TBool compare(const TChar* str1,const TChar* str2);
public:
	String():_str(NULL),_len(0){}
	~String();
	typedef TChar* const refferString;
	String(const TChar* str,TInt size = -1,TInt len = -1);
	String(staticString& str,TInt len = -1);
	String(dynamicString& str,TInt len = -1);
	String(managedString& str,TInt len = -1);
	String(const String& str);
	virtual TBool cloneFrom(const Object* other);
	virtual StringPtr toString(StringPtr str = StringPtr());
	TVoid operator =(const String& str);
	TUint getLength();
	TUint getSize();
	TVoid resetLength();
	TChar* toCharString()const{return _str;};
	TBool copyFrom(const TChar* str, TInt len = -1);
	TVoid clear();
	String* operator ->(){return this;}
private:
	TChar* _str;
	TInt   _len;
	TInt   _size;
};	
//////////////////////////////////////////////////////////////////////////
class StringBuilder : public Object
{
	DECL_RTTI1(StringBuilder,Object);
public:
	StringBuilder();
	~StringBuilder();
	StringBuilder* append(StringPtr& str);
	StringBuilder* append(String::staticString& str);
	StringBuilder* append(String::dynamicString& str);
	StringBuilder* append(const TChar* str,TInt len = 0);
	StringPtr toString(StringPtr str = StringPtr());
	void clear();
private:
	class StringNode : public Memory
	{
	public:
		StringPtr str;
		StringNode* next;
	};
	StringNode* _head;
	StringNode* _rear;
	TUint _totalLength;
};
}
#endif // skyString_h__